package com.demo.wrapper.interfaces;

import com.demo.wrapper.constance.DefaultValueConstance;
import com.demo.wrapper.enums.AggEnum;
import com.demo.wrapper.pojo.Agg;
import com.demo.wrapper.pojo.Order;

import java.util.function.Consumer;

/**
 * 聚合拼接接口
 *
 * @param <Wrapper>    条件拼接类，需继承Limit接口
 * @param <AggWrapper> 聚合拼接类，需继承Agg接口
 * @author arthur_zhou
 */
public interface IEsAggWrapper<AggWrapper extends IEsAggWrapper<AggWrapper, Wrapper>, Wrapper extends IEsLimitWrapper<Wrapper, AggWrapper>> extends IBaseWrapper<AggWrapper> {

    /**
     * 分组统计
     * column,count(*) group by column
     *
     * @param name   聚合名
     * @param column 聚合字段
     * @return this
     */
    default AggWrapper terms(String name, String column) {
        return terms(name, column, DefaultValueConstance.SIZE, Order.count(false), Order.key(true));
    }

    /**
     * 分组统计
     * column,count(*) group by column
     *
     * @param name   聚合名
     * @param column 聚合字段
     * @param size   返回值
     * @return this
     */
    default AggWrapper terms(String name, String column, int size) {
        return terms(name, column, size, Order.count(false), Order.key(true));
    }

    /**
     * 分组统计
     * column,count(*) group by column
     *
     * @param name   聚合名
     * @param column 聚合字段
     * @param orders 排序
     * @return this
     */
    default AggWrapper terms(String name, String column, Order... orders) {
        return terms(name, column, DefaultValueConstance.SIZE, orders);
    }

    /**
     * 分组统计
     * column,count(*) group by column
     *
     * @param name   聚合名
     * @param column 聚合字段
     * @param size   返回值
     * @param orders 排序
     * @return this
     */
    default AggWrapper terms(String name, String column, int size, Order... orders) {
        return setAgg(new Agg(AggEnum.TERMS, name, column, size, orders));
    }

    /**
     * 统计
     * count(column)
     *
     * @param name   聚合名
     * @param column 聚合字段
     * @return this
     */
    default AggWrapper count(String name, String column) {
        return setAgg(new Agg(AggEnum.VALUE_COUNT, name, column));
    }

    /**
     * 去重统计
     * count(distinct column)
     *
     * @param name   聚合名
     * @param column 聚合字段
     * @return this
     */
    default AggWrapper cardinality(String name, String column) {
        return setAgg(new Agg(AggEnum.CARDINALITY, name, column));
    }

    /**
     * 平均值
     * avg(column)
     *
     * @param name   聚合名
     * @param column 聚合字段
     * @return this
     */
    default AggWrapper avg(String name, String column) {
        return setAgg(new Agg(AggEnum.AVG, name, column));
    }

    /**
     * 值相加
     * sum(column)
     *
     * @param name   聚合名
     * @param column 聚合字段
     * @return this
     */
    default AggWrapper sum(String name, String column) {
        return setAgg(new Agg(AggEnum.SUM, name, column));
    }

    /**
     * 最大值
     * min(column)
     *
     * @param name   聚合名
     * @param column 聚合字段
     * @return this
     */
    default AggWrapper max(String name, String column) {
        return setAgg(new Agg(AggEnum.MAX, name, column));
    }

    /**
     * 最小值
     * min(column)
     *
     * @param name   聚合名
     * @param column 聚合字段
     * @return this
     */
    default AggWrapper min(String name, String column) {
        return setAgg(new Agg(AggEnum.MIN, name, column));
    }

    /**
     * 详细信息
     * count(column),avg(column),sum(column),min(column),min(column)
     *
     * @param name   聚合名
     * @param column 聚合字段
     * @return this
     */
    default AggWrapper stats(String name, String column) {
        return setAgg(new Agg(AggEnum.STATS, name, column));
    }

    /**
     * 过滤
     *
     * @param name
     * @param wrapper
     * @return
     */
    default AggWrapper filter(String name, Wrapper wrapper) {
        return setAgg(new Agg(AggEnum.FILTER, name, null, wrapper));
    }

    /**
     * 子聚合
     *
     * @param consumer
     * @return this
     */
    default AggWrapper agg(Consumer<AggWrapper> consumer) {
        AggWrapper aggWrapper = instanceChild();
        consumer.accept(aggWrapper);
        return addAggChildren(aggWrapper);
    }

    /**
     * 设置聚合
     *
     * @param agg
     * @return this
     */
    AggWrapper setAgg(Agg agg);

    /**
     * 添加子聚合
     *
     * @param child
     * @return this
     */
    AggWrapper addAggChildren(AggWrapper child);


}
